package com.yxt.qmgf.minesweeper.service;

import cn.hutool.extra.spring.SpringUtil;
import com.yxt.qmgf.common.ClientSession;
import com.yxt.qmgf.common.ImageSrc;
import com.yxt.qmgf.minesweeper.ctrl.mineController;
import com.yxt.qmgf.minesweeper.model.Cell;
import com.yxt.qmgf.userinfo.dao.UserInfoDao;
import com.yxt.qmgf.userinfo.vo.UserInfoVO;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.h2.engine.User;

import java.net.URL;
import java.util.Arrays;
import java.util.Optional;
import java.util.Random;

public class GameBoard {
    private final int rows;
    private final int cols;
    private final int mineCount;
    private final Cell[][] cells;
    private boolean gameOver = false;
    private int flagsPlaced = 0;
    private int secondsElapsed = 0;
    private Label mineCountLabel;
    private Label timerLabel;
    private Timeline timeline;
    private Stage currentStage;

    private UserInfoVO vo;

    private int score = 0;

    Image icon = new Image(ImageSrc.mine_logo_path);
    private GridPane gridPane;

    private boolean primaryPressed = false;
    private boolean secondaryPressed = false;
    private Cell lastHoveredCell = null;

    public GameBoard(int rows, int cols, int mineCount, UserInfoVO vo) {
        this.rows = rows;
        this.cols = cols;
        this.mineCount = mineCount;
        this.cells = new Cell[rows][cols];
        this.vo = vo;
        initializeCells();  // 初始化单元格
        placeMines();       // 放置地雷
        calculateAdjacentMines(); // 计算相邻地雷数
    }

    public BorderPane createBoard() {
        BorderPane borderPane = new BorderPane();
        this.gridPane = new GridPane();

        // 计算格子大小（动态调整）
        int cellSize = calculateCellSize();

        // 设置网格布局
        gridPane.setPadding(new Insets(10)); // 内边距
        gridPane.setHgap(1); // 水平间距
        gridPane.setVgap(1); // 垂直间距

        // 加载CSS
        loadCSS(borderPane);

        // 添加格子
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                Button btn = cells[row][col].getButton();
                btn.setMinSize(cellSize, cellSize);
                btn.setPrefSize(cellSize, cellSize);
                btn.setMaxSize(cellSize, cellSize);
                gridPane.add(btn, col, row);
            }
        }

        // 创建状态栏
        createStatusBar();

        // 组装UI
        borderPane.setTop(new HBox(10, mineCountLabel, timerLabel));
        borderPane.setCenter(gridPane);

        // 计算窗口最小尺寸
        calculateWindowSize(borderPane, cellSize);

        return borderPane;
    }

    private int calculateCellSize() {
        // 根据格子数量动态调整大小
        if (rows * cols > 500) return 20;  // 大型网格
        if (rows * cols > 200) return 25;  // 中型网格
        return 30;                         // 小型网格
    }

    private void calculateWindowSize(BorderPane borderPane, int cellSize) {
        // 计算内容区域所需尺寸
        double contentWidth = cols * cellSize + (cols - 1) * gridPane.getHgap() + 20;
        double contentHeight = rows * cellSize + (rows - 1) * gridPane.getVgap() + 50;

        // 设置最小尺寸
        borderPane.setMinSize(contentWidth, contentHeight);
    }

    private void loadCSS(BorderPane borderPane) {
        borderPane.getStylesheets().clear(); // 先清除现有样式

        URL cssUrl = getClass().getResource("/css/minesweeper.css");
        if (cssUrl != null) {
            borderPane.getStylesheets().add(cssUrl.toExternalForm());
        } else {
            System.err.println("警告: CSS文件未找到，使用默认样式");
            // 设置一些默认样式
            gridPane.setStyle("-fx-background-color: #f0f0f0;");
        }
    }


    private void createStatusBar() {
        mineCountLabel = new Label("雷数: " + (mineCount - flagsPlaced));
        timerLabel = new Label("时间: 0");

        // 设置标签样式
        mineCountLabel.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;");
        timerLabel.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;");

        timeline = new Timeline(new KeyFrame(Duration.seconds(1), e -> {
            secondsElapsed++;
            timerLabel.setText("时间: " + secondsElapsed);
        }));
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }

    public void stopTimer() {
        if (timeline != null) {
            timeline.stop();
        }
    }

    public void toggleFlag(Cell cell) {
        if (!cell.isRevealed()) {
            cell.toggleFlag();
            flagsPlaced += cell.isFlagged() ? 1 : -1;

            // 计分逻辑：如果标记的是地雷则得分
            if (cell.isFlagged() && cell.isMine()) {
                score++;
                System.out.println("正确标记地雷！当前得分: " + score);
            } else if (!cell.isFlagged() && cell.isMine()) {
                // 取消标记则扣分
                score--;
            }

            mineCountLabel.setText("雷数: " + (mineCount - flagsPlaced));
        }
    }
    private void initializeCells() {
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                cells[row][col] = new Cell(row, col);
                setupCellActions(cells[row][col]);
            }
        }
    }

    private void placeMines() {
        Random random = new Random();
        int minesPlaced = 0;

        while (minesPlaced < mineCount) {
            int row = random.nextInt(rows);
            int col = random.nextInt(cols);

            if (!cells[row][col].isMine()) {
                cells[row][col].setMine(true);
                minesPlaced++;
            }
        }
    }

    private void calculateAdjacentMines() {
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                if (!cells[row][col].isMine()) {
                    int mines = countAdjacentMines(row, col);
                    cells[row][col].setAdjacentMines(mines);
                }
            }
        }
    }

    private int countAdjacentMines(int row, int col) {
        int count = 0;

        for (int r = Math.max(0, row - 1); r <= Math.min(rows - 1, row + 1); r++) {
            for (int c = Math.max(0, col - 1); c <= Math.min(cols - 1, col + 1); c++) {
                if (cells[r][c].isMine()) {
                    count++;
                }
            }
        }

        return count;
    }


    // 新增方法：计算周围旗帜数
    private long countAdjacentFlags(int row, int col) {
        long count = 0;
        for (int r = Math.max(0, row-1); r <= Math.min(rows-1, row+1); r++) {
            for (int c = Math.max(0, col-1); c <= Math.min(cols-1, col+1); c++) {
                if ((r != row || c != col) && cells[r][c].isFlagged()) {
                    count++;
                }
            }
        }
        return count;
    }

    private void setupCellActions(Cell cell) {
        // 移除所有现有事件处理器
        cell.getButton().setOnMousePressed(null);
        cell.getButton().setOnMouseReleased(null);
        cell.getButton().setOnMouseClicked(null);

        // 新的事件处理逻辑
        cell.getButton().addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
            System.out.printf("PRESSED [%d][%d] %s %n",
                    cell.getRow(), cell.getCol(), event.getButton());

            if (event.getButton() == MouseButton.PRIMARY) {
                primaryPressed = true;
            } else if (event.getButton() == MouseButton.SECONDARY) {
                secondaryPressed = true;
            }

            // 实时检测双键按下
            if (primaryPressed && secondaryPressed) {
                System.out.println("DUAL BUTTON PRESSED");
                if (cell.isRevealed() || !cell.isFlagged()) {
                    highlightAdjacentCells(cell);
                }
                event.consume();
            }
        });

        cell.getButton().addEventHandler(MouseEvent.MOUSE_RELEASED, event -> {
            System.out.printf("RELEASED [%d][%d] %s %n",
                    cell.getRow(), cell.getCol(), event.getButton());

            if (event.getButton() == MouseButton.PRIMARY) {
                primaryPressed = false;
            } else if (event.getButton() == MouseButton.SECONDARY) {
                secondaryPressed = false;
            }

            // 自动揭示检查
            if (!primaryPressed && !secondaryPressed && lastHoveredCell != null) {
                if (lastHoveredCell.isRevealed() &&
                        lastHoveredCell.getAdjacentMines() > 0) {
                    tryAutoReveal(lastHoveredCell);
                }
            }

            // 延迟100ms清除高亮，避免闪烁
            new Thread(() -> {
                try { Thread.sleep(100); }
                catch (InterruptedException e) {}
                Platform.runLater(this::clearHighlights);
            }).start();
        });

        // 简化单击处理
        cell.getButton().setOnMouseClicked(event -> {
            if (primaryPressed || secondaryPressed || gameOver) return;

            if (event.getButton() == MouseButton.PRIMARY && !cell.isFlagged()) {
                revealCell(cell);
            } else if (event.getButton() == MouseButton.SECONDARY) {
                toggleFlag(cell);
            }
        });
    }
    private void highlightAdjacentCells(Cell centerCell) {
        clearHighlights();

        // 中心格子高亮
        centerCell.getButton().getStyleClass().add("center-highlight");
        System.out.println("高亮中心格子: " + centerCell.getRow() + "," + centerCell.getCol());

        // 修正后的周围格子高亮逻辑
        for (int r = Math.max(0, centerCell.getRow() - 1);
             r <= Math.min(rows - 1, centerCell.getRow() + 1); r++) {
            for (int c = Math.max(0, centerCell.getCol() - 1);
                 c <= Math.min(cols - 1, centerCell.getCol() + 1); c++) {
                if ((r != centerCell.getRow() || c != centerCell.getCol()) &&
                        !cells[r][c].isRevealed()) {
                    cells[r][c].setHighlighted(true);
                    System.out.println("高亮周围格子: " + r + "," + c);
                }
            }
        }
    }

    private void clearHighlights() {
        System.out.println("清除所有高亮");
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                cells[r][c].getButton().getStyleClass().remove("highlighted-cell");
                cells[r][c].getButton().getStyleClass().remove("center-highlight");
                cells[r][c].setHighlighted(false); // 确保Cell内部状态也更新
            }
        }
    }
    private void revealCell(Cell cell) {
        if (cell.isRevealed() || cell.isFlagged()) {
            return;
        }

        cell.reveal();
        // 确保添加数字类
        if (!cell.isMine() && cell.getAdjacentMines() > 0) {
            cell.getButton().getStyleClass().add("number-" + cell.getAdjacentMines());
        }

        if (cell.isMine()) {
            gameOver(false,vo);
            revealAllMines();
            return;
        }

        if (cell.getAdjacentMines() == 0) {
            revealAdjacentCells(cell.getRow(), cell.getCol());
        }

        checkWinCondition();
    }

    private void revealAdjacentCells(int row, int col) {
        for (int r = Math.max(0, row - 1); r <= Math.min(rows - 1, row + 1); r++) {
            for (int c = Math.max(0, col - 1); c <= Math.min(cols - 1, col + 1); c++) {
                if (!cells[r][c].isRevealed() && !cells[r][c].isMine()) {
                    revealCell(cells[r][c]);
                }
            }
        }
    }

    private void revealAllMines() {
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                if (cells[row][col].isMine()) {
                    cells[row][col].reveal();
                }
            }
        }
    }
    public void gameOver(boolean won,UserInfoVO vo) {
        gameOver = true;
        stopTimer();
        revealAllMines();
        // 显示游戏结束信息
        int finalScore = calculateFinalScore();
        Platform.runLater(() -> {
            Alert gameOverAlert = new Alert(Alert.AlertType.CONFIRMATION);
            Stage stage = (Stage) gameOverAlert.getDialogPane().getScene().getWindow();
            stage.getIcons().add(icon);
            gameOverAlert.setTitle("游戏结束");
            String resultMessage = won ? "恭喜你扫除所有地雷！" : "很遗憾，地雷炸了！";
            gameOverAlert.setHeaderText(resultMessage + "\n最终得分: " + finalScore +"\n所得积分会存储到账户中");
            FileScoreService.addRecord(vo.getUsername(), finalScore,vo.getScore());
            vo.setScore(String.valueOf(Integer.parseInt(vo.getScore())+finalScore));
            SpringUtil.getBean(UserInfoDao.class).UpdateByVo(vo);
            ButtonType restart = new ButtonType("重新开始");
            ButtonType newGame = new ButtonType("新游戏");
            ButtonType exit = new ButtonType("退出");

            gameOverAlert.getButtonTypes().setAll(restart, newGame, exit);

            Optional<ButtonType> result = gameOverAlert.showAndWait();
            result.ifPresent(buttonType -> {
                if (buttonType == restart) {
                    restartGame();
                } else if (buttonType == newGame) {
                    if (currentStage != null) {
                        currentStage.close();
                    }
                    // 通过控制器启动新游戏
                    mineController controller = new mineController();
                    controller.showDifficultyDialog();
                } else if (buttonType == exit) {
                    if (currentStage != null) {
                        currentStage.close();
                    }
                }
            });
        });
    }

    private int calculateFinalScore() {
        int correctFlags = 0;
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                Cell cell = cells[row][col];
                if (cell.isFlagged() && cell.isMine()) {
                    correctFlags++;
                }
            }
        }
        return correctFlags;
    }
    private void checkWinCondition() {
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                if (!cells[row][col].isMine() && !cells[row][col].isRevealed()) {
                    return;
                }
            }
        }
        gameOver(true,vo);
        // 游戏胜利逻辑
    }

    private void tryAutoReveal(Cell centerCell) {
        System.out.printf("尝试自动揭开 [%d][%d] 数字=%d%n",
                centerCell.getRow(), centerCell.getCol(),
                centerCell.getAdjacentMines());

        if (!centerCell.isRevealed() || centerCell.getAdjacentMines() == 0) {
            System.out.println("格子未揭开或数字为0，不处理");
            return;
        }

        long flagCount = countAdjacentFlags(centerCell.getRow(), centerCell.getCol());
        System.out.printf("周围旗帜数: %d (需要 %d)%n",
                flagCount, centerCell.getAdjacentMines());

        if (flagCount == centerCell.getAdjacentMines()) {
            System.out.println("旗帜匹配，开始自动揭开");
            for (int r = Math.max(0, centerCell.getRow() - 1);
                 r <= Math.min(rows - 1, centerCell.getRow() + 1); r++) {
                for (int c = Math.max(0, centerCell.getCol() - 1);
                     c <= Math.min(cols - 1, centerCell.getCol() + 1); c++) {
                    if ((r != centerCell.getRow() || c != centerCell.getCol()) &&
                            !cells[r][c].isRevealed() && !cells[r][c].isFlagged()) {
                        System.out.printf("自动揭开 [%d][%d]%n", r, c);
                        revealCell(cells[r][c]);
                    }
                }
            }
        } else {
            System.out.println("旗帜数量不匹配");
        }
    }

    public void restartGame() {
        stopTimer();
        gameOver = false;
        flagsPlaced = 0;
        secondsElapsed = 0;

        // 完全重新初始化
        initializeCells();
        placeMines();
        calculateAdjacentMines();

        Platform.runLater(() -> {
            if (gridPane != null) {
                gridPane.getChildren().clear();
                for (int row = 0; row < rows; row++) {
                    for (int col = 0; col < cols; col++) {
                        Button btn = cells[row][col].getButton();
                        gridPane.add(btn, col, row);
                    }
                }
                mineCountLabel.setText("雷数: " + mineCount);
                timerLabel.setText("时间: 0");
            }
        });

        timeline.playFromStart();
    }

    public Stage getCurrentStage() {
        return currentStage;
    }

    public void setCurrentStage(Stage currentStage) {
        this.currentStage = currentStage;
    }
}
